from ..common import *
from .. import config as SCONFIGS

__all__ = [
    'get_location_from_viewspy', # 定位视图在文件中的位置
]

def get_location_from_viewspy(app_name: str, def_class_name: str):
    """定位 视图 在 视图文件 中的位置（搜索根路径、指定路径、甚至递归所有的文件【最后仍找不到时会找site-packages系统路径】；搜索匹配所有的别名）
    
        app_name: 应用程序名称
        def_class_name: 视图方法名/类名
        找所有可能的路径（项目根路径、自定义根路径），找到立即返回
        返回三元组：行、列、文件路径
        【匹配即返回的原则】
    """
    # if "" == app_name or "" == def_class_name:
    if "" == def_class_name:
        return (1, 0, None) # 默认第一行，第一个字符
        
    patt_def = re.compile(r"^def\s*" + def_class_name + r"\s*\(")
    patt_class = re.compile(r"^class\s*" + def_class_name + r"\s*\(")
    view_alias = env.get_file_alias('views') # 获取视图所有的别名
    app_names: list[str] = djangotools.get_appnames_by_dirname(djangotools.SCONFIGS.dirname()) # 获取所有可能的应用程序名

    # 从 app_names 中匹配与 app_name 最匹配的一个（用非标准匹配标准，防止解析错误）
    judge_split_name = app_name.split('.')
    for temp_name in app_names:
        if temp_name.split('.')[-1] in judge_split_name:
            app_name = temp_name
            break

    # 查找原则：先常规查找，后指定路径查找、最后递归式地毯查找
    '''
        常规查找，根路径查找（最高优先级）、而后 指定路径查找
    '''
    common_path = os.path.join(SCONFIGS.dirname(), *app_name.split('.')) # 默认路径
    dirnames = [common_path, *env.get_obj_rootpaths('views')] # 所有可能的视图存在的路径
    for dirname in dirnames:
        for _ in view_alias:
            view_path = os.path.join(dirname, _)
            if os.path.exists(view_path):
                for i, line in enumerate(read_file_list_del_comment(view_path)):
                    if patt_def.search(line):
                        return (i+1, 0, view_path)
                    if patt_class.search(line):
                        return (i+1, 0, view_path)
    '''
        仍找不着时，发起递归式查找（称之为没有办法的办法）
    '''
    search_path = os.path.join(common_path, '**', '*.py')
    objs = glob.glob(search_path, recursive=True)
    for obj in objs:
        for _ in view_alias:
            if os.path.isfile(obj) and os.path.basename(obj) == _:
                for i, line in enumerate(read_file_list_del_comment(obj)):
                    if patt_def.search(line):
                        return (i+1, 0, obj)
                    if patt_class.search(line):
                        return (i+1, 0, obj)

    '''
        如果还是没有找到，尝试从python的 site-packages 目录中获取
    '''
    search_path = os.path.join(env.get_path_by_env_order(), '**', '*.py')
    objs = glob.glob(search_path, recursive=True)
    for obj in objs:
        for _ in view_alias:
            if os.path.isfile(obj) and os.path.basename(obj) == _:
                for i, line in enumerate(read_file_list_del_comment(obj)):
                    if patt_def.search(line):
                        return (i+1, 0, obj)
                    if patt_class.search(line):
                        return (i+1, 0, obj)

    return (1, 0, None)
